package com.ingenico.insider.swing;

import java.awt.Component;
import java.nio.ByteOrder;
import java.util.logging.Logger;

import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

import com.ingenico.tools.nio.channel.SampleLength;
import com.ingenico.tools.nio.channel.SampleSign;

public class JRawFormatChooser {
	private static final Logger _logger = Logger.getLogger(JRawFormatChooser.class.getCanonicalName());

	private static ByteOrder[] availableOrders = new ByteOrder[] {
		ByteOrder.LITTLE_ENDIAN,
		ByteOrder.BIG_ENDIAN
	};

	private static SampleLength[] availableLengths = new SampleLength[] {
		SampleLength.BYTE,
		SampleLength.SHORT,
		SampleLength.FLOAT,
		SampleLength.DOUBLE
	};

	private static SampleSign[] availableSigns = new SampleSign[] {
		SampleSign.SIGNED,
		SampleSign.UNSIGNED
	};

	private final JLabel message;
	private final ButtonGroup lengthsGroup;
	private final int formatsIndex = 1;
	private final ButtonGroup signsGroup;
	private final int signsIndex = 1;
	private final ButtonGroup ordersGroup;
	private final int ordersIndex = 0;
	
	private final JTextField sampleRateField;

	private final JCheckBox noInteraction;

	private final Object[] paneComponents;

    private void initDialog() {
        final JPanel formatsPanel = new JPanel();
        formatsPanel.setBorder(new TitledBorder("Format"));
		JRadioButton radioButton;
		for (int i = 0; i < availableLengths.length; i++) {
			SampleLength currentFormat = availableLengths[i];

			radioButton = new JRadioButton(currentFormat.toString());
			radioButton.setActionCommand(Integer.toString(i));
			if (formatsIndex == i) {
				radioButton.setSelected(true);
			}
			lengthsGroup.add(radioButton);
			formatsPanel.add(radioButton);
		}

        final JPanel signsPanel = new JPanel();
        signsPanel.setBorder(new TitledBorder("Signedness"));
		for (int i = 0; i < availableSigns.length; i++) {
			SampleSign currentSign = availableSigns[i];

			radioButton = new JRadioButton(currentSign.toString());
			radioButton.setActionCommand(Integer.toString(i));
			if (signsIndex == i) {
				radioButton.setSelected(true);
			}
			signsGroup.add(radioButton);
			signsPanel.add(radioButton);
		}

		final JPanel ordersPanel = new JPanel();
        ordersPanel.setBorder(new TitledBorder("Byte Orders"));
		for (int i = 0; i < availableOrders.length; i++) {
			ByteOrder currentOrder = availableOrders[i];

			radioButton = new JRadioButton(currentOrder.toString());
			radioButton.setActionCommand(Integer.toString(i));
			if (ordersIndex == i) {
				radioButton.setSelected(true);
			}
			ordersGroup.add(radioButton);
			ordersPanel.add(radioButton);
		}

		final JPanel sampleRatePanel = new JPanel();
		sampleRatePanel.setBorder(new TitledBorder("Sample Rate"));
		sampleRatePanel.add(sampleRateField);

		paneComponents[0] = message;
		paneComponents[1] = formatsPanel;
		paneComponents[2] = signsPanel;
		paneComponents[3] = ordersPanel;
		paneComponents[4] = sampleRatePanel;
		paneComponents[5] = noInteraction;
    }

	public JRawFormatChooser() {
		message = new JLabel();
		lengthsGroup = new ButtonGroup();
		signsGroup = new ButtonGroup();
		ordersGroup = new ButtonGroup();
// TODO: think about using JFormattedTextField or a better validation method...
		sampleRateField = new JTextField(8);
		noInteraction = new JCheckBox("Use these settings for all curves");
		paneComponents = new Object[6];
        initDialog();
	}

	public int showRawFormatDialog(Component parentComponent, final String message) {
		this.message.setText(message);
        return JOptionPane.showOptionDialog(
        	parentComponent,
        	paneComponents,
        	"Choose RAW File Format",
        	JOptionPane.OK_CANCEL_OPTION,
        	JOptionPane.QUESTION_MESSAGE,
        	null,
        	null,
        	null
        );
	}

	public ByteOrder getOrder() {
		String command = ordersGroup.getSelection().getActionCommand();
		return (ByteOrder)availableOrders[Integer.parseInt(command)];
	}

	public SampleSign getSign() {
		String command = signsGroup.getSelection().getActionCommand();
		return (SampleSign)availableSigns[Integer.parseInt(command)];
	}

	public SampleLength getFormat() {
		String command = lengthsGroup.getSelection().getActionCommand();
		return (SampleLength)availableLengths[Integer.parseInt(command)];
	}

	public int getSampleRate() {
		String command = sampleRateField.getText();
		try {
			return Integer.parseInt(command);
		} catch (NumberFormatException nfe) {
			_logger.severe("Sample rate is not a valid integer number (" + command + ").");
			return 0;
		}
	}

	public boolean isInteractionDisabled() {
		return noInteraction.isSelected();
	}
	
	public void setInteractionDisabled(boolean interaction) {
		noInteraction.setSelected(interaction);
	}
}
